<?php
/**
 * 汇友科技
 * @copyright (c) 2017 http://www.huiyou365.net All rights reserved.
 * @author: Creatint <creatint@163.com>
 */

namespace Common\Model;

use Think\Model as ModelThink;
use Common\Contract\Model as ModelContract;
use Closure;
use Think\Page;

class Model extends ModelThink implements ModelContract{

    private $offset;

    // 主键名称
    private $id = 'id';


    /**
     * 获取列表，原生数据.
     *
     * @param null $query
     * @param bool $field 需要的字段
     * @param bool $showPage 是否显示分页数据
     * @return mixed
     */
    public function get($query = null, $field = true, $order = '', $showPage = true, Closure $closure = null ){
        $order || $order = $this->id . ' DESC';
        $map = [];
        if ($query !== null) {
            foreach ($query as $key => $value) {
                if ($value !== null) {
                    $map[$key] = $value;
                }
            }
        }

        // 是否显示分页数据
        if ( $showPage ) {
            $res = $this
                ->where($map)
                ->order($order)
                ->page(I('get.p',0) . ',' . C('LIST_ROWS'))
                ->field($field)
                ->select();
            $count = $this->where($map)->count();
            $this->page = show_page(new Page($count, C('LIST_ROWS')));
        } else {
            $res = $this
                ->where($map)
                ->order($order)
                ->field($field)
                ->select();
        }

        // 其他处理
        if ( $closure ) {
            $res = $closure($res);
        }

        return $res;
    }

    /**
     * 获取单条数据.
     *
     * @param null $query
     * @param bool $field
     * @param Closure $closure
     * @return mixed
     */
    public function info($query = null, $field = true, Closure $closure = null){
        $map = array();
        if (is_numeric($query) && $query > 0) {
            $map['id'] = $query;
        } else {
            $query = (array)$query;
            // 遍历条件
            foreach($query as $k=>$v){
                $map[$k] = $v;
            }
        }


        // 获取单条数据
        $res = $this
            ->where($map)
            ->field($field)
            ->find();

        // 有闭包则传入闭包
        if ( $closure ) {
            $res = $closure($res);
        }

        return $res;
    }


    /**
     * 更新数据.
     *
     * @param $data
     * @return bool
     */
    public function update($data){
        // 默认使用$_POST
        if( !$data ) {
            $data = $_POST;
        }

        // 程序出口值,0:失败, >1:成功, 以位运算的或运算来修改其值,新增成功则返回id值,因此在控制器中应该以$_POST['id']为主
        $res = 0;

        if (!($data = $this->create($data))) {
            goto RES;
        }

        if ($data['id'] > 0 && $this->save($data)) {
            $res = $data['id'];
            goto RES;
        }

        if (!$data['id'] && $id = $this->add($data)) {
            $res = $id;
            goto RES;
        }

        // 程序出口
        RES:
        return $res;
    }


    public function remove($id){
        if ( !$id ) {
            $this->error = '待删除项为空';
            return false;
        }

        $map = [];

        if (is_array($id)) {
            $map = [
                'id'=>[
                    'IN',
                    $id
                ]
            ];
        } else {
            if (is_numeric($id)) {
                $id = (array)(int)$id;
            } else if ( is_string($id) && strpos($id, ',') > 0) {
                $id = preg_split('/[,，;\r\n]+/', trim($id, ",，;\r\n"));
            }

            $map = [
                'id'=>[
                    'IN',
                    $id
                ]
            ];
        }



        if ( !$id ) {
            $this->error = '待删除项为空';
            return false;
        }

        if ( $this->where($map)->delete() ) {
            return true;
        } else {
            return false;
        }
    }

    public function next( $info )
    {
        $map = array(
            'status'    =>  1,
            'updated_at'  =>  array('lt', $info['updated_at'])
        );
        $res = $this->where($map)->find();

        return $res;
    }
    public function prev( $info )
    {
        $map = array(
            'status'    =>  1,
            'updated_at'  =>  array('gt', $info['updated_at'])
        );
        $res = $this->where($map)->find();
        return $res;
    }

    public function position($pos = null, $limit = null, $field = null, $status = 1){
        // 查询条件
        $map = $this->map($status, $pos);

        // 设置列表数量
        is_numeric($limit) && $this->limit($limit);

        // 进行查询
        $this->lists = $this
            ->where($map)
            ->order('updated_at DESC')
            ->select();

        return $this;
    }

    public function map($status = 1, $pos = null){
        $map = array();

        // 状态
        $map['status']  =   $status;

        // 推荐位
        if ( $pos >0 )
            $map[]  =   "position & {$pos} = {$pos}";

        return $map;
    }

    public function getLists(){
        return $this->lists;
    }

    public function getPage(){
        return $this->page;
    }

    public function getError(){
        return $this->error;
    }

    /**
     * Determine if the given attribute exists.
     *
     * @param  mixed  $offset
     * @return bool
     */
    public function offsetExists($offset)
    {
        return isset($this->$offset);
    }

    /**
     * Get the value for a given offset.
     *
     * @param  mixed  $offset
     * @return mixed
     */
    public function offsetGet($offset)
    {
        return $this->$offset;
    }

    /**
     * Set the value for a given offset.
     *
     * @param  mixed  $offset
     * @param  mixed  $value
     * @return void
     */
    public function offsetSet($offset, $value)
    {
        $this->$offset = $value;
    }

    /**
     * Unset the value for a given offset.
     *
     * @param  mixed  $offset
     * @return void
     */
    public function offsetUnset($offset)
    {
        unset($this->$offset);
    }

    public function id( $id = null ){
        if ( $id ) {
            $this->id = $id;
        } else {
            return $id;
        }
    }
}
